package com.ruoyi.framework.filter;

import com.ruoyi.common.annotation.IgnoreAuth;
import com.ruoyi.common.constant.ApiConstants;
import com.ruoyi.common.enums.BusinessCode;
import com.ruoyi.common.json.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysToken;
import com.ruoyi.system.service.ISysTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Set;

/*
 * @Author chencundeng
 * @Description api 过滤类
 * @Date 2019/2/21
 **/
@Component
public class ApiInterceptorAdapter extends HandlerInterceptorAdapter {

    @Autowired
    private ISysTokenService iSysTokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers","X-Requested-With,Host,User-Agent,Accept,Accept-Language,Accept-Encoding,Accept-Charset,Keep-Alive,Connection,Referer,Origin, Content-Type,authorization");

        String requestPath = getRequestPath(request);// 用户访问的资源地址
    	/*if(requestPath.contains("swagger") || requestPath.contains("api-docs")){
			return true;
		}*/

        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }

        //如果有@IgnoreAuth注解，则不验证token
        if (annotation != null&&annotation.value().equals("ignoreAuth")) {
            return true;
        }

        //从header中获取token
        String token = request.getHeader(ApiConstants.LOGIN_TOKEN_KEY);
        //如果header中不存在token，则从参数中获取token
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(ApiConstants.LOGIN_TOKEN_KEY);
        }

        if(annotation != null&&annotation.value().equals("userAuth")){   //token为空直接返回不拦截
            if (StringUtils.isBlank(token)) {
                return true;
            }

            //查询token信息
            SysToken sysToken = iSysTokenService.selectSysTokenByToken(token);
            if (sysToken != null&&sysToken.getExpireTime().getTime() > System.currentTimeMillis()) {
                //设置userId到request里，后续根据userId，获取用户信息
                request.setAttribute(ApiConstants.LOGIN_USER_KEY, sysToken.getUserId());
            }

            return true;

        }

        //token为空
        if (StringUtils.isBlank(token)) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = null ;
            JSONObject res = new JSONObject();
            res.put("code",BusinessCode.NOT_LOGIN.getValue()+"");
            res.put("msg",BusinessCode.NOT_LOGIN.getDesc());
            out = response.getWriter();
            out.append(res.toString());
            return  false;
            //throw new ApiRRException("请先登录", BusinessCode.NOT_LOGIN.getValue());
        }

        //查询token信息
        SysToken sysToken = iSysTokenService.selectSysTokenByToken(token);
        if (sysToken == null || sysToken.getExpireTime().getTime() < System.currentTimeMillis()) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = null ;
            JSONObject res = new JSONObject();
            res.put("code",BusinessCode.UNIQUE_TOKEN.getValue()+"");
            res.put("msg",BusinessCode.UNIQUE_TOKEN.getDesc());
            out = response.getWriter();
            out.append(res.toString());
            return  false;
            //throw new ApiRRException("token失效，请重新登录", BusinessCode.ACCESS_TOKEN.getValue());
        }

        //设置userId到request里，后续根据userId，获取用户信息
        request.setAttribute(ApiConstants.LOGIN_USER_KEY, sysToken.getUserId());

        return true;

    }

    /**
     * 截取访问路径
     *
     * @param request
     * @return
     */
    public static String getRequestPath(HttpServletRequest request) {
        ServletContext servletContext=request.getServletContext();
        //使用ServletContext获取指定目录下所有资源路径

        Set<String> paths=servletContext.getResourcePaths("/META-INF/resources");

        //System.out.println(paths);//[/WEB-INF/lib, /WEB-INF/classes,/WEB-INF/web.xml]
        String requestPath = request.getRequestURI();
        // 去掉其他参数
        if (requestPath.indexOf("&") > -1) {
            requestPath = requestPath.substring(0, requestPath.indexOf("&"));
        }
        // 去掉jsessionid参数
        if(requestPath.indexOf(";") > -1){
            requestPath = requestPath.substring(0, requestPath.indexOf(";"));
        }
        // 去掉项目路径
        requestPath = requestPath.substring(request.getContextPath().length() + 1);
        return requestPath;
    }

}
